home *** CD-ROM | disk | FTP | other *** search
- #include <stdio.h>
- #include <conio.h>
- #include "global.h"
- #include "config.h"
- #ifdef AX25
- #include "mbuf.h"
- #include "ax25.h"
- #include "timer.h"
- #include "trace.h"
- #include "socket.h"
-
- static char * near decode_type(int type) {
- switch(type){
- case I:
- return "I";
- case SABM:
- return "SABM";
- case DISC:
- return "DISC";
- case DM:
- return "DM";
- case UA:
- return "UA";
- case RR:
- return "RR";
- case RNR:
- return "RNR";
- case REJ:
- return "REJ";
- case FRMR:
- return "FRMR";
- case UI:
- return "UI";
- default:
- return "[invalid]";
- }
- }
-
- /* Figure out the frame type from the control field
- * This is done by masking out any sequence numbers and the
- * poll/final bit after determining the general class (I/S/U) of the frame
- */
- static int near ftype(int control)
- {
- if((control & 1) == 0) /* An I-frame is an I-frame... */
- return I;
- if(control & 2) /* U-frames use all except P/F bit for type */
- return (control & ~PF);
- else /* S-frames use low order 4 bits for type */
- return (control & 0x0f);
- }
-
- /* Dump an AX.25 packet header */
- void ax25_dump(FILE *fp,struct mbuf **bpp,int check)
- {
- char tmp[AXBUF], tmp1[AXBUF], frmr[3], cp[2 * AXALEN];
- int control, pid, seg, ipcam, cmdrsp, type, dama_master, unsegmented = 0;
- struct mbuf *bp;
-
- trprintf(fp,"AX25: ");
-
- if(pullup(bpp,cp,2 * AXALEN) == (2 * AXALEN)) {
- dama_master = DAMA - (cp[ALEN + AXALEN] & DAMA);
- trprintf(fp,"%s->%s ",pax25(tmp,&cp[AXALEN]),pax25(tmp1,cp));
-
- if(((cp[ALEN]) & C) == (cp[ALEN + AXALEN] & C))
- cmdrsp = VERS1;
- else
- cmdrsp = (cp[ALEN] & C) ? DST_C : SRC_C;
-
- if((cp[ALEN + AXALEN] & E) == 0) {
- trprintf(fp,"v ");
- while((cp[ALEN] & E) == 0) {
- if(pullup(bpp,cp,AXALEN) == AXALEN)
- trprintf(fp,"%s%s ",pax25(tmp,cp),(cp[ALEN] & REPEATED) ? "*" : "");
- else
- goto err;
- }
- }
- } else {
- goto err;
- }
-
- if((control = PULLCHAR(bpp)) == -1) {
- err:
- trprintf(fp,"bad header\n");
- return;
- }
-
- trprintf(fp,"%s",decode_type((type = ftype(control))));
-
- if(control & PF) {
- switch(cmdrsp) {
- case CMD:
- trprintf(fp,"(P)");
- break;
- case RESP:
- trprintf(fp,"(F)");
- break;
- default:
- trprintf(fp,"(P/F)");
- break;
- }
- }
-
- /* Dump sequence numbers */
- if((type & 0x3) != U) /* I or S frame? */
- trprintf(fp," NR=%d",(control>>5)&7);
- if(type == I || type == UI){
- if(type == I)
- trprintf(fp," NS=%d",(control>>1)&7);
- /* Decode I field */
- if((pid = PULLCHAR(bpp)) != -1){ /* Get pid */
- if(pid == PID_SEGMENT){
- seg = PULLCHAR(bpp);
- trprintf(fp,"%s remain %u",seg & SEG_FIRST ? " First seg;" : "",seg & SEG_REM);
- if(seg & SEG_FIRST)
- pid = PULLCHAR(bpp);
- } else
- unsegmented = 1;
-
- /* IPCAM-feature - DB3FL.910104 */
- bp = *bpp;
- if(pid == PID_NO_L3 && bp->cnt >= 20
- && bp->data[0] == 0x45
- && bp->data[1] == 0x00
- && bp->data[2] < 0x02) {
- pid = PID_IP;
- ipcam = 1;
- } else
- ipcam=0;
- /* */
-
- if (dama_master)
- trprintf(fp," [DAMA]");
-
- if(pid == PID_SEGMENT)
- trprintf(fp,"\n");
- else {
- textattr(WHITE);
- trprintf(fp," pid=");
- switch(pid){
- case PID_ARP:
- textattr(YELLOW);
- trprintf(fp,"ARP\n");
- arp_dump(fp,bpp);
- break;
- case PID_NETROM:
- textattr(BLUE);
- trprintf(fp,"NET/ROM\n");
- #ifdef NETROM
- /* Don't verify checksums unless unsegmented */
- netrom_dump(fp,bpp,unsegmented);
- #endif
- break;
- case PID_IP:
- textattr(YELLOW);
- if(ipcam)
- trprintf(fp,"IPCAM\n");
- else
- trprintf(fp,"IP\n");
- /* Don't verify checksums unless unsegmented */
- ip_dump(fp,bpp,unsegmented);
- break;
- case PID_X25:
- trprintf(fp,"X.25\n");
- break;
- case PID_TEXNET:
- trprintf(fp,"TEXNET\n");
- break;
- case PID_FLEXNET:
- textattr(MAGENTA);
- trprintf(fp,"FLEXNET\n");
- #ifdef FLEXNET
- flexnet_dump(fp,bpp); /* to be written */
- #endif
- break;
- case PID_NO_L3:
- textattr(WHITE);
- trprintf(fp,"Text\n");
- break;
- default:
- textattr(RED);
- trprintf(fp,"0x%x\n",pid);
- }
- }
- }
- } else if(type == FRMR && pullup(bpp,frmr,3) == 3){
- trprintf(fp,"\nVr=%d Vs=%d",(frmr[1] >> 5) & MMASK,(frmr[1] >> 1) & MMASK);
- if(frmr[2] & W)
- trprintf(fp," Invalid control field");
- if(frmr[2] & X)
- trprintf(fp," Illegal I-field");
- if(frmr[2] & Y)
- trprintf(fp," Too-long I-field");
- if(frmr[2] & Z)
- trprintf(fp," Invalid seq number");
- trprintf(fp,": %s\n",decode_type(ftype(frmr[0])));
- } else
- trprintf(fp," %s\n",dama_master ? "[DAMA] " : "");
- }
-
-
- /* Return 1 if this packet is directed to us, 0 otherwise. Note that
- * this checks only the ultimate destination, not the digipeater field
- */
- int ax_forus(struct iface *iface,struct mbuf *bp) {
- return (addreq(bp->data,iface->hwaddr));
- }
-
- #endif /* AX25 */